<?php

require_once("vendor/symfony_yaml/sfYamlParser.php");
require_once("pipes/BasePipe.class.php");

class Controller
{
	private $special_components = array("cacher", "logger");
	private $experiment_parser;
	private $experiment_config;
	
	public function __construct()
	{
		$this->experiment_parser = new sfYamlParser();
		
	}
	
	private function build_component($component_type, $component_config)
	{
		
		require_once($component_type."s/".$component_config["name"].".class.php");
		
		foreach($this->special_components as $component)
		{
			if(isset($component_config[$component]))
			{
				$component_config[$component]["object"] = $this->build_component($component, $component_config[$component]);
			}
		}
		return new $component_config["name"]($component_config);
	}
	
	public function run($experiment_name)
	{
		try{
		$this->experiment_config = $this->experiment_parser->parse(file_get_contents('experiments/'.$experiment_name.'.yml'));
		} catch (Exception $e)
		{
			echo $e;
			die();
		}
		//We build the main logger
		
		$this->logger = $this->build_component("logger", $this->experiment_config["logger"]);
		
		$this->logger->log_info("Building the Reader");
		$this->reader = $this->build_component("reader", $this->experiment_config["reader"]);
		
		$this->logger->log_info("Building the Writer");
		$this->writer = $this->build_component("writer",$this->experiment_config["writer"]);
		
		$pipes_config = $this->experiment_config["pipes"];
		
		$i = 0;
		while ($record = $this->reader->read_record())
		{
			$i++;
			$this->logger->log_debug("Reading Record $i: ".implode(", ", $record));
			foreach($pipes_config as $pipe_name => $pipe_config)
			{
				$pipe = $this->build_component("pipe", $pipe_config);
				$this->logger->log_debug("Transforming Record $i in pipe ".$pipe_config["name"]);
				$record = $pipe->transform_record($record);
			}
			$this->logger->log_debug("Writing Record $i" );
			$this->writer->write_record($record);
		}
		
		$this->logger->log_info("Closing the Reader");
		$this->reader->close();
		$this->logger->log_info("Closing the Writer");
		$this->writer->close();
		$this->logger->log_info("Closing the Logger");
		$this->logger->close();
		
	}
}
